package com.ruoyi.common.utils.equipment;

import java.util.Arrays;

//对接收到的FC502M通讯命令进行解析，逐字节解析
public class C502MframeCompile{
	private static int iRXDStep=0;//接收数据的步骤
	private static byte bRXDbuf[]=new byte[16];//接收到的十六进制数值
	private static boolean bRXDTranslate=false;//接收到转移码
	private static int iRXDDataIndex=0;//接收到缓存索引
	private static C502Mframe oRxFrame;
	private static void IniRXDValue(){
		iRXDStep=0;
		Arrays.fill(bRXDbuf,(byte)0);
		bRXDTranslate=false;
		iRXDDataIndex=0;
		oRxFrame = new C502Mframe();
	}

	//加入数据至缓冲中
	private static void AddRxData(byte src)
	{
		if(iRXDDataIndex==0){
			//第一次收到数据，初始化缓存
			Arrays.fill(bRXDbuf,(byte)0);
		}
		bRXDbuf[iRXDDataIndex++]=src;

	}
	//返回解析完毕的类对象
	public static C502Mframe GetRxFrame()
	{
		return oRxFrame;

	}

	//对每个字节进行检查
	//返回 true表示对命令检测完毕。false 表示命令检测没有通过，需要继续。
	public static boolean CompileData(byte src)
	{
		int iData=ConverterTool.uByte(src);

		//检查是否接收到命令起始标识
		if(iData==126)//7e
		{
			IniRXDValue();
			return false;
		}

		//检查是否接收到转译码
		if(iData==127)//7f
		{
			bRXDTranslate=true;
			return false;
		}

		if(bRXDTranslate)
		{	//检查转译码是否正确
			switch (iData)
			{
				case 1:
					iData=126;//7f 01=7e
					break;
				case 2:
					iData=127;//7f 02=7f
					break;
				default:
					IniRXDValue();
					return false;
			}
			bRXDTranslate=false;
		}
		//开始按格式进行计算
		switch (iRXDStep)
		{
			case 0://机器号
				oRxFrame.SetAddr(iData);	//保存
				iRXDStep++;//进行到下一步
				iRXDDataIndex = 0;
				return false;
			case 1://信息代码
				if(iRXDDataIndex!=2) //未收到2个字节，继续接收
				{
					AddRxData(src);
					if(iRXDDataIndex==2)
					{
						int tmpCode =(ConverterTool.uByte(bRXDbuf[0])<<8)+ConverterTool.uByte(bRXDbuf[1]);
						oRxFrame.SetCode(tmpCode);	//保存
						iRXDDataIndex=0;
						iRXDStep++;//进行到下一步
					}
				}
				else{
					iRXDDataIndex=0;//溢出过边界
					return false;
				}

			case 2://命令类型
				oRxFrame.SetCmdType(iData);	//保存
				iRXDStep++;//进行到下一步
				return false;
			case 3://命令参数
				oRxFrame.SetCmdPar(iData);	//保存
				iRXDStep++;//进行到下一步
				return false;
			case 4://数据长度
				oRxFrame.SetDataLen(iData);

				iRXDStep++;//进行到下一步
				iRXDDataIndex = 0;
				if( iData != 0 )
				{
					oRxFrame.SetDatabuffSize(oRxFrame.GetDataLen());
				}
				else
				{
					//跳过存储数据步骤
					iRXDStep++;
				}
				return false;

			case 5://命令数据
				if(iRXDDataIndex!=oRxFrame.GetDataLen()) //未收到指定的字节，继续接收
				{
					oRxFrame.SetDataValue(iRXDDataIndex++,src);//保存

					if(iRXDDataIndex==oRxFrame.GetDataLen())
					{
						iRXDDataIndex=0;
						iRXDStep++;//进行到下一步
					}
				}else{
					iRXDDataIndex=0;//溢出过边界
					return false;
				}
			case 6://计算检验和
				iRXDStep++;//进行到下一步
				oRxFrame.Create();
				if (oRxFrame.GetCheckData() == iData)
				{
					return true;//检验和通过
				}
				else{
					return false;
				}
			default:
				IniRXDValue();
				return false;
		}
	}
}
